package com.example.utils.util.LongAdd;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @Description     AtomicLong内部采用 CAS 的方式实现，里面主要使用了一个 long 类型的 value 作为成员变量，然后使用循环的 CAS 操作去操作 value 的值，
 *                            并发量比较大的情况下，CAS 操作失败的概率较高，内部失败了会重试，导致耗时可能会增加，导致性能比 synchronized 还低一些。
 *                            并发量不是太大的情况下，CAS 性能还是可以的。
 *                  AtomicLong属于 JUC 中的原子类，还不是很熟悉的可以看一下：JUC 中原子类，一篇就够了(https://mp.weixin.qq.com/s?__biz=MzkwNTI4NDQ2NA==&mid=2247485257&idx=1&sn=b20783bc5d7582a200479b5478df07c5&scene=21#wechat_redirect)
 * @ClassName Demo1
 * @Author xiaojiang
 * @Date 2022/3/2 上午 10:19
 */
public class Demo1 {

    static AtomicLong count = new AtomicLong(0);

    public static void incr() {
        count.incrementAndGet();
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        for (int i = 0; i < 10; i++) {
            count.set(0);
            m1();
        }
    }

    private static void m1() throws InterruptedException {
        long t1 = System.currentTimeMillis();
        int threadCount = 50;
        CountDownLatch countDownLatch = new CountDownLatch(threadCount);
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                try {
                    for (int j = 0; j < 1000000; j++) {
                        incr();
                    }
                } finally {
                    countDownLatch.countDown();
                }
            }).start();
        }
        countDownLatch.await();
        long t2 = System.currentTimeMillis();
        System.out.println(String.format("结果：%s,耗时(ms)：%s", count, (t2 - t1)));
    }
}
